﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Workbench.Models;
using Workbench.Persistance;
using Workbench.Shared;

namespace Workbench.Operations
{
    public static class LemmatizerOperations
    {
        public static List<WordModel> GetWords(ProjectFileModel file)
        {
            var lemmaRepo = DBContext.Current.GetLemmatizerRepository();
            List<POSTypeModel> posTypes = null;
            using (var projectRepo = DBContext.Current.GetBuildRepository())
            {
                posTypes = flatten(projectRepo.GetPOSTypes());
            }
            var result = lemmaRepo.GetAllWords(file, posTypes.ToDictionary(x=>x.RowId));
            return result;
        }

        private static List<POSTypeModel> flatten(IEnumerable<POSTypeModel> items)
        {
            var result = new List<POSTypeModel>();
            foreach (var item in items)
            {
                result.Add(item);
                if (item.Children.Count > 0)
                {
                    result.AddRange(flatten(item.Children));
                }
            }
            return result;
        }

        public static Task<List<WordModel>> GetWordsAsync(long fileId)
        {
            return Task.Run(() =>
            {
                using (var buildRepo = DBContext.Current.GetBuildRepository())
                {
                    var file = buildRepo.GetFileById(fileId);
                    return GetWords(file);
                }
            });
        }

        public static Task<List<WordModel>> GetWordsAsync(ProjectFileModel projectFileModel)
        {
            return Task.Run(() => {
                return GetWords(projectFileModel);
            });
        }

        public static List<BaseFormModel> GetBaseFormSuggestions(string currentBaseWordContent)
        {
            if (currentBaseWordContent == null) return new List<BaseFormModel>();
            var lemmaRepo = DBContext.Current.GetLemmatizerRepository();
            return lemmaRepo.GetBaseFormSuggestions(currentBaseWordContent);
        }

        public static string GetSentence(WordModel word)
        {
            var textRepo = DBContext.Current.GetTextRepository();
            return textRepo.GetSentenceContent(word);
        }

        public static BaseFormModel AddBaseForm(string content)
        {
            Debug.Assert(!string.IsNullOrWhiteSpace(content));
            var repo = DBContext.Current.GetLemmatizerRepository();
            var baseForm = new BaseFormModel() { Content = content };
            repo.PersistBaseForm(baseForm);
            Debug.Assert(baseForm.RowId != 0);
            return baseForm;
        }

        public static void UpdateBaseFormForWords(string baseFormContent, WordModel word)
        {
            UpdateBaseFormForWords(baseFormContent, new WordModel[] { word }); 
        }

        public static void UpdateBaseFormForWords(string baseFormContent, IEnumerable<WordModel> words)
        {
            var lemmaRepo = DBContext.Current.GetLemmatizerRepository();
            var baseForm = new BaseFormModel()
            {
                Content = baseFormContent
            };
            lemmaRepo.PersistBaseForm(baseForm);
            Debug.Assert(baseForm.RowId != 0);
            lemmaRepo.UpdateBaseFormForWords(baseForm, words);
        }

        public static void UpdateBaseFormForWordsInFile(long baseFormId, long uniqueWordId, long fileId)
        {
            var lemmaRepo = DBContext.Current.GetLemmatizerRepository();
            lemmaRepo.UpdateBaseFormForWords(baseFormId, uniqueWordId, fileId);
        }

        public static void UpdateBaseFormForWordsInAllFiles(long baseFormId, long uniqueWordId)
        {
            var lemmaRepo = DBContext.Current.GetLemmatizerRepository();
            lemmaRepo.UpdateBaseFormForWords(baseFormId, uniqueWordId);
        }

        public static void ClearBaseFormForWords(IEnumerable<WordModel> words)
        {
            var lemmaRepo = DBContext.Current.GetLemmatizerRepository();
            lemmaRepo.UpdateBaseFormForWords(new BaseFormModel() { RowId = 0 }, words);
        }

        public static void ClearBaseFormForWordsInFile(long uniqueWordId, long fileId)
        {
            var lemmaRepo = DBContext.Current.GetLemmatizerRepository();
            lemmaRepo.UpdateBaseFormForWords(0, uniqueWordId, fileId);
        }

        public static void ClearBaseFormForWordsInAllFiles(long uniqueWordId)
        {
            var lemmaRepo = DBContext.Current.GetLemmatizerRepository();
            lemmaRepo.UpdateBaseFormForWords(0, uniqueWordId);
        }

        public static void DeleteBaseForm(BaseFormModel baseFormModel, IEnumerable<WordModel> availableWords)
        {
            var lemmaRepo = DBContext.Current.GetLemmatizerRepository();
            lemmaRepo.DeleteBaseForm(baseFormModel);
            foreach (var word in availableWords)
            {
                word.BaseForm = null;
                word.BaseFormId = 0;
            }
        }
    }
}
